#pragma once

// Structs used by save-state file

// *** DON'T CHANGE ANY STRUCT WITHOUT CONSIDERING BACKWARDS COMPATIBILITY WITH SAVED STATE FORMAT ***

#define MAKE_VERSION(a,b,c,d) ((a<<24) | (b<<16) | (c<<8) | (d))

typedef struct
{
	DWORD dwTag;
	DWORD dwVersion;
	DWORD dwChecksum;
} SS_FILE_HDR;

typedef struct
{
	DWORD dwLength;		// Byte length of this unit struct
	DWORD dwVersion;
} SS_UNIT_HDR;

/////////////////////////////////////////////////////////////////////////////////

const UINT nMemMainSize = 64*1024;
const UINT nMemAuxSize = 64*1024;

typedef struct
{
	BYTE A;
	BYTE X;
	BYTE Y;
	BYTE P;
	BYTE S;
	USHORT PC;
	unsigned __int64 g_nCumulativeCycles;
	UINT32 g_bmIRQ;
	UINT32 g_bmNMI;
	BOOL g_bNmiFlank;
	ULONG g_nCyclesSubmitted;
	ULONG g_nCyclesExecuted;
	signed int g_nIrqCheckTimeout;
	bool g_bCritSectionValid;
	unsigned __int64 g_nCycleIrqStart;
	unsigned __int64 g_nCycleIrqEnd;
	UINT g_nCycleIrqTime;
	UINT g_nIdx;
	UINT g_nBuffer[4096];
	UINT g_nMean;
	UINT g_nMin;
	UINT g_nMax;
} SS_CPU6502;

typedef struct
{
	unsigned __int64 g_nJoyCntrResetCycle;
} SS_IO_Joystick;

typedef struct
{
	DWORD keyboardqueries;
	BYTE  keycode;
	BOOL  keywaiting;
} SS_IO_Keyboard;

typedef struct
{
	unsigned __int64 g_nSpkrLastCycle;
} SS_IO_Speaker;

typedef struct
{
	bool bAltCharSet;	// charoffs
	DWORD dwVidMode;
} SS_IO_Video;

typedef struct
{
	DWORD dwMemMode;
	BOOL bLastWriteRam;
	BYTE nMemMain[nMemMainSize];
	BYTE nMemAux[nMemAuxSize];
} SS_BaseMemory;

typedef struct
{
    eApple2Type g_Apple2Type; //gu - for now doesn't change (always 2e) - may change in the future
    DWORD     cyclenum;            // Used by SpkrToggle() for non-wave sound
    DWORD     emulmsec;
    DWORD       emulmsec_frac;
    bool      g_bFullSpeed;
    double      g_fCurrentCLK6502;
    DWORD       g_dwCyclesThisFrame;
} SS_CACore;

typedef struct
{
	SS_UNIT_HDR UnitHdr;
	SS_CPU6502 CPU6502;
	SS_IO_Joystick Joystick;
	SS_IO_Keyboard Keyboard;
	SS_IO_Speaker Speaker;
	SS_IO_Video Video;
	SS_BaseMemory Memory;
	SS_CACore CACore; //added to store stuff from CACore.cpp
} SS_APPLE2_Unit;


/////////////////////////////////////////////////////////////////////////////////

typedef struct
{
	SS_UNIT_HDR UnitHdr;
	DWORD dwType;		// SS_CARDTYPE
	DWORD dwSlot;		// [1..7]
} SS_CARD_HDR;

enum SS_CARDTYPE
{
	CT_Empty = 0,
	CT_Disk2,			// Apple Disk][
};

/////////////////////////////////////////////////////////////////////////////////

typedef struct
{
	SS_CARD_HDR	Hdr;
} SS_CARD_EMPTY;

/////////////////////////////////////////////////////////////////////////////////

const UINT NIBBLES_PER_TRACK = 0x1A00;

typedef struct
{
	int		track;
	int		phase;
	int		byte;
	BOOL	writeprotected;
	BOOL	trackimagedata;
	BOOL	trackimagedirty;
	DWORD	spinning;
	DWORD	writelight;
	int		nibbles;
	BOOL    diskindrive;
	int     disksize;
	BYTE	nTrack[NIBBLES_PER_TRACK];
	TCHAR      filename[MAX_PATH]; //gu - added this one and rest of this struct
	DWORD      format;
	DWORD      offset;
	BOOL       validtrack[40]; //hard coded from TRACKS_MAX = 35 + 5 (std plus extra)
	UINT       uNumTracks;
} DISK2_Unit;

typedef struct
{
	SS_CARD_HDR	Hdr;
	DISK2_Unit	Unit[2];
    WORD    phases;
	WORD	currdrive;
	BOOL	diskaccessed;
	BOOL	enhancedisk;
	BYTE	floppylatch;
	BOOL	floppymotoron;
	BOOL	floppywritemode;
	UINT    g_uNumTracksInImage; //actually in DiskImage
} SS_CARD_DISK2;

/////////////////////////////////////////////////////////////////////////////////

typedef struct
{
	SS_FILE_HDR Hdr;
	SS_APPLE2_Unit Apple2Unit;
	SS_CARD_DISK2 Disk2;				// Slot6
} CACore_SNAPSHOT;

/////////////////////////////////////////////////////////////////////////////////
